import { sha256 } from 'js-sha256'
export default {
  isEmpty (val) {
    if (val === null || val === undefined || val === '' || val === 'null' || JSON.stringify(val) === '{}' || val.length === 0) {
      return true
    }
    return false
  },
  setSha256 (data) {
    let password = ''
    password = sha256(data)
    return password
  },
  jsonToString (data) {
    let str = []
    for (let p in data) {
      if (data.hasOwnProperty(p) && !this.isEmpty(data[p])) {
        str.push(encodeURIComponent(p) + '=' + encodeURIComponent(data[p]))
      }
    }
    return str.join('&')
  },

  /**
    * 判断字符串是否键盘三连（横着、竖着）
    * @param {String} str
    * @returns boolean 是否满足键盘3连键
    */
  checkKeyboardContinuousChar (str) {
    const isKeyboardContinuousChar = (str, keyboard) => {
      str = str.toLowerCase().split('') // 不区分大小写
      // 获取坐标位置
      const y = []
      const x = []
      for (let c = 0; c < str.length; c++) {
        y[c] = 0// 当做~`键处理
        x[c] = -1
        for (let i = 0; i < keyboard.length; i++) {
          for (let j = 0; j < keyboard[i].length; j++) {
            if (str[c] === keyboard[i][j]) {
              y[c] = i
              x[c] = j
            }
          }
        }
        if (x[c] !== -1) continue
      }
      // 匹配坐标连线
      for (let c = 1; c < str.length - 1; c++) {
        // 横着同一行
        if (y[c - 1] === y[c] && y[c] === y[c + 1]) {
          // 从左往右或者从右往左一排
          if ((x[c - 1] + 1 === x[c] && x[c] + 1 === x[c + 1]) || (x[c + 1] + 1 === x[c] && x[c] + 1 === x[c - 1])) {
            return true
          }
        }
        // 竖着同一列
        if (x[c - 1] === x[c] && x[c] === x[c + 1]) {
          // 从下往上或者从下往下同一列
          if ((y[c - 1] + 1 === y[c] && y[c] + 1 === y[c + 1]) || (y[c + 1] + 1 === y[c] && y[c] + 1 === y[c - 1])) {
            return true
          }
        }
        // 竖着同一列（类似/而不是\的一列）
        if ((x[c - 1] + 1 === x[c] && x[c] + 1 === x[c + 1]) || (x[c - 1] - 1 === x[c] && x[c] - 1 === x[c + 1])) {
          // 从下往上或者从下往下同一列
          if ((y[c - 1] + 1 === y[c] && y[c] + 1 === y[c + 1]) || (y[c + 1] + 1 === y[c] && y[c] + 1 === y[c - 1])) {
            return true
          }
        }
      }
      return false
    }
    const keyboard1 = [
      ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '='],
      ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\'],
      ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\''],
      ['z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/']
    ]
    // shift键
    const keyboard2 = [
      ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+'],
      ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '{', '}', '|'],
      ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ':', '"'],
      ['z', 'x', 'c', 'v', 'b', 'n', 'm', '<', '>', '?']
    ]
    const isKeyboardContinuousChar1 = isKeyboardContinuousChar(str, keyboard1)
    const isKeyboardContinuousChar2 = isKeyboardContinuousChar(str, keyboard2)
    if (isKeyboardContinuousChar1 || isKeyboardContinuousChar2) {
      return true
    } else {
      return false
    }
  },

  /**
    * 判断字符串是否连续数字或字母(3位及以上)，如123，Abc
    * @param {String} str
    * @return boolean 是否满足连续数字或字母(3位及以上)
    */
  checkContinuousDigitCharOrletter (str) {
    const isDigitChar = (char) => {  
      return /^\d$/.test(char)
    } 
    const isLetter = (char) => {  
      return /^[a-z]$/.test(char)
    }
    let lowStr = str.toLowerCase() // 不区分大小写
    const strLen = lowStr.length
    if (strLen < 3) return false
    let flag = false
    for (let i = 1; i < strLen - 1; i++) {
      let firstIndex = lowStr[i - 1].charCodeAt()
      let secondIndex = lowStr[i].charCodeAt()
      let thirdIndex = lowStr[i + 1].charCodeAt()
      if ( (isDigitChar(lowStr[i - 1]) && isDigitChar(lowStr[i]) && isDigitChar(lowStr[i + 1])) // 三个连续数字
          || (isLetter(lowStr[i - 1]) && isLetter(lowStr[i]) && isLetter(lowStr[i + 1])) ) { // 三个连续字母
        if ((thirdIndex - secondIndex === 1) && (secondIndex - firstIndex === 1)) {
          flag = true
          break
        }
      }
    }
    return flag
  },

  /**
    * 判断字符串是否有连续相同数字、字母、或特殊字符(3位及以上)，如111，aaa，AAa
    * @param {String} str
    * @return boolean 是否满足连续相同数字、字母、或特殊字符(3位及以上)
    */
  checkContinuousSameChar (str) {
    const reg = /(\w)*(\w)\2{2}(\w)*/gi // 连续相同数字、字母(不区分大小写)
    const reg2 = /(\W)*(\W)\2{2}(\W)*/g // 连续相同特殊字符
    if (reg.test(str) || reg2.test(str)) {
      return true
    } else {
      return false
    }
  },

  /**
   * @param {String} str 
   * @returns boolean 是否满足至少包含一个特殊字符（英文特殊字符，$除外）
   */
  containsSpecialCharacter(str) {
    // 英文特殊字符
    const specialChars = ['`', '~', '!', '@', '#', '%', '^', '&', '*', '(', ')', 
                          '-', '_', '=', '+', '[', ']', '{', '}', '\\', '|', ';', 
                          ':', '\'', '"', ',', '<', '.', '>', '?', '/']
    let specialCharacterStr = str.match(/[^a-zA-Z0-9]/g) || [] // 匹配非字母、数字的字符
    let isSpecialCharsSubset = specialCharacterStr.every(item => specialChars.includes(item)) // 是否是限定的字符集
    if (!isSpecialCharsSubset) return false
    return specialChars.some(char => specialCharacterStr.includes(char)) // 是否包含一个特殊字符
  },
  
  checkReservedWords (originStr) {
    const reservedWords = ['redhat', 'abc', 'abcd', 'cmcc', 'cmss', 'ydy', 'yidongyun', 'admin', 'root', 'mts', 'postgres', 'linux', 'password', 'passw0rd'] // 密码中不应包含的文字
    let str = originStr.toLocaleLowerCase()
    for (const item of reservedWords) {
      if (str.indexOf(item) !== -1) {
        return true
      }
    }
  },
  // 手机/邮箱脱敏
  phoneOrEmailMask(str, type) {
    if ( !str ) return ''
    if ( str === '--' ) return '--'
    let maskRes = str
    let emailArr = []
    if (type === 'email') {
      emailArr = str.split('@')
      // 邮箱脱敏规则不涵盖邮箱后缀，仅对@字符前的内容生效
      maskRes = emailArr[0]
    }
    const maskResLen = maskRes.length
    // 总长度2位字符时，第二个字符脱敏
    if ( maskResLen === 2 ) {
      maskRes = maskRes[0] + '*'
    }
    // 总长度在2-5位字符时，中间字符脱敏
    if ( maskResLen >2 && maskResLen <= 5) {
      maskRes = maskRes[0] + '*'.repeat(maskResLen - 2) + maskRes[maskResLen - 1]
    }
    // 6-20位之间，前后各保留2位，中间位置的字符脱敏
    if (maskResLen >= 6 && maskResLen <= 20) {
      maskRes = maskRes.slice(0, 2) + '*'.repeat(maskResLen - 4) + maskRes.slice(- 2)
    }
    // 20位以上，前后各保留4位
    if (maskResLen > 20) {
      maskRes = maskRes.slice(0, 4) + '*'.repeat(maskResLen - 8) + maskRes.slice(- 4)
    }
    return type === 'email' ? maskRes + '@' + emailArr[1] : maskRes
  },
  // 对象赋值
  assignObj(objTarget, data) {
    Object.keys(objTarget).forEach(key => {
      if (data.hasOwnProperty(key)) {
        objTarget[key] = data[key]
      }
    })
  },
  // 查找数组中对象中某个属性值等于某个值的对象
  findLabelObjByProp(obj, key) {
    return obj.find(item => item.value === key)?.label
  },
  // 跳转地址校验
  validURL(sUrl) {
    return !!((/^(https?:\/\/)?[\w\-.]+\.(qq|tencent)\.com($|\/|\\)/i).test(sUrl) || (/^[\w][\w/.\-_%]+$/i).test(sUrl) || (/^[/\\][^/\\]/i).test(sUrl))
  }
}